package com.ktg.mes.wm.service.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.ktg.common.core.domain.Result;
import com.ktg.common.utils.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktg.common.utils.SecurityUtils;
import com.ktg.mes.md.domain.MdItem;
import com.ktg.mes.md.service.IMdItemService;
import com.ktg.mes.pro.domain.ProItemNeed;
import com.ktg.mes.pro.service.IProItemNeedService;
import com.ktg.mes.unit.other.ZLServiceIml;
import com.ktg.mes.util.LGLeftJoinQueryWrapper;
import com.ktg.mes.util.LGQueryWrapper;
import com.ktg.common.core.domain.model.SqlResult;
import com.ktg.mes.wm.domain.WmItemRecptLine;
import com.ktg.mes.wm.service.IWmItemRecptLineService;
import com.ktg.mes.wm.service.IWmMaterialStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import com.ktg.mes.wm.mapper.WmStockOutMapper;
import com.ktg.mes.wm.domain.WmStockOut;
import com.ktg.mes.wm.service.IWmStockOutService;
import org.springframework.transaction.annotation.Transactional;


/**
 * 产品出库(备货)记录Service业务层处理
 *
 * @author byteco
 * @date 2022-12-15
 */
@Service
public class WmStockOutServiceImpl extends ZLServiceIml<WmStockOutMapper, WmStockOut> implements IWmStockOutService
{

    @Autowired
    private IWmStockOutService wmStockOutService;

    @Autowired
    private IProItemNeedService proItemNeedService;

    @Autowired
    private IWmItemRecptLineService wmItemRecptLineService;

    @Autowired
    private IMdItemService mdItemService;


    @Autowired
    private IWmMaterialStockService wmMaterialStockService;

    /**
     * 查询产品出库(备货)记录
     *
     * @param entity 产品出库(备货)记录
     * @param page 分页对象
     * @return 产品出库(备货)记录
     */
    @Override
    public IPage<WmStockOut> queryPageList(WmStockOut entity, Page<WmStockOut> page) {
        LGQueryWrapper<WmStockOut> lqw = new LGQueryWrapper<>(entity,null);
        lqw.orderByDesc("create_time");
        IPage<WmStockOut> pageList = this.page(page, lqw);
        return pageList;
    }

    /**
     * 查询产品出库(备货)记录
     *
     * @param entity 产品出库(备货)记录
     * @return 产品出库(备货)记录
     */
    @Override
    public List<WmStockOut> queryList(WmStockOut entity) {
        QueryWrapper<WmStockOut> lqw = new QueryWrapper<WmStockOut>(entity);
        lqw.orderByDesc("create_time");
        return this.list(lqw);
    }

    public WmStockOut getInfo(Long id)
    {
        return this.getById(id);
    }


    /**
     * 新增产品出库(备货)记录
     *
     * @param entity 产品出库(备货)记录
     * @return 结果
     */
    @Override
    public SqlResult insert(WmStockOut entity)
    {
        entity.setCreateBy(SecurityUtils.getUsername());
        entity.setCreateTime(DateUtils.getNowDate());
        return insertSQLModel(entity);
    }

    /**
     * 修改产品出库(备货)记录
     *
     * @param entity 产品出库(备货)记录
     * @return 结果
     */
    @Override
    public SqlResult update(WmStockOut entity)
    {
        entity.setUpdateBy(SecurityUtils.getUsername());
        entity.setUpdateTime(DateUtils.getNowDate());
        return updateSQLModel(entity);
    }

    /**
     * 批量删除产品出库(备货)记录
     *
     * @param recordIds 需要删除的产品出库(备货)记录主键
     * @return 结果
     */
    @Override
    public boolean delete(Long[] recordIds)
    {
        boolean flag = true;
        for (int i = 0;i < recordIds.length;i++){
            SqlResult result = delete(recordIds[i]);
            if (!result.isSuccess()){
                flag = false;
            }
        }
        return flag;
    }

    /**
     * 删除产品出库(备货)记录信息
     *
     * @param recordId 产品出库(备货)记录主键
     * @return 结果
     */
    @Override
    public SqlResult delete(Long recordId)
    {
        return deleteSQLId(recordId);
    }

    private LambdaQueryWrapper<WmStockOut> buildQueryWrapper(WmStockOut entity) {
        LambdaQueryWrapper<WmStockOut> lqw = Wrappers.lambdaQuery();
//                    lqw.eq(StringUtils.isNotBlank(entity.getItemCode()), WmStockOut::getItemCode, entity.getItemCode());
//                    lqw.like(StringUtils.isNotBlank(entity.getItemName()), WmStockOut::getItemName, entity.getItemName());
//                    lqw.eq(StringUtils.isNotBlank(entity.getSpecification()), WmStockOut::getSpecification, entity.getSpecification());
//                    lqw.eq(StringUtils.isNotBlank(entity.getUnitOfMeasure()), WmStockOut::getUnitOfMeasure, entity.getUnitOfMeasure());
//                    lqw.eq(StringUtils.isNotBlank(entity.getViscosity()), WmStockOut::getViscosity, entity.getViscosity());
//                    lqw.eq(StringUtils.isNotBlank(entity.getTag()), WmStockOut::getTag, entity.getTag());
//                    lqw.eq(StringUtils.isNotBlank(entity.getPackingType()), WmStockOut::getPackingType, entity.getPackingType());
//                    lqw.eq(StringUtils.isNotBlank(entity.getBatchNo()), WmStockOut::getBatchNo, entity.getBatchNo());
//                    lqw.eq(StringUtils.isNotBlank(entity.getPrefix()), WmStockOut::getPrefix, entity.getPrefix());
//                    lqw.eq(entity.getSerialNumber() != null, WmStockOut::getSerialNumber, entity.getSerialNumber());
//                    lqw.eq(entity.getPrintNumber() != null, WmStockOut::getPrintNumber, entity.getPrintNumber());
//                    lqw.eq(StringUtils.isNotBlank(entity.getWarehouseId()), WmStockOut::getWarehouseId, entity.getWarehouseId());
//                    lqw.eq(StringUtils.isNotBlank(entity.getWarehouseCode()), WmStockOut::getWarehouseCode, entity.getWarehouseCode());
//                    lqw.like(StringUtils.isNotBlank(entity.getWarehouseName()), WmStockOut::getWarehouseName, entity.getWarehouseName());
                    lqw.eq(entity.getQuantity() != null, WmStockOut::getQuantity, entity.getQuantity());
                    lqw.eq(entity.getStatus() != null, WmStockOut::getStatus, entity.getStatus());
        return lqw;
    }


    public IPage<JSONObject> lgPageMapList(LGLeftJoinQueryWrapper queryWrapper){
        Long count = getBaseMapper().allCount(queryWrapper.getQueryModel());
        List<JSONObject> list = getBaseMapper().pageList(queryWrapper.getQueryModel());
        if (queryWrapper.getDefaultDateFormat() != null){
            convertJsonDateValue(list,queryWrapper);
        };
        IPage<JSONObject> iPage = new IPage<JSONObject>() {
            @Override
            public List<OrderItem> orders() {
                return null;
            }

            @Override
            public List<JSONObject> getRecords() {
                return list;
            }

            @Override
            public IPage<JSONObject> setRecords(List<JSONObject> records) {
                return null;
            }

            @Override
            public long getTotal() {
                return count;
            }

            @Override
            public IPage<JSONObject> setTotal(long total) {
                return null;
            }

            @Override
            public long getSize() {
                return queryWrapper.getPageSize();
            }

            @Override
            public IPage<JSONObject> setSize(long size) {
                return null;
            }

            @Override
            public long getCurrent() {
                return queryWrapper.getPageIndex();
            }

            @Override
            public IPage<JSONObject> setCurrent(long current) {
                return null;
            }
        };
        return iPage;
    };

    public void convertJsonDateValue(List<JSONObject> list,LGLeftJoinQueryWrapper queryWrapper){
        List<String> dateKey = null;
        for (JSONObject jsonObject:list) {

            if (dateKey == null){
                dateKey = new ArrayList();
                Set<String> keySet = queryWrapper.getAsColumnList();
                for (String key: keySet) {
                    String mKey = key;
                    if (mKey.startsWith("\"") && mKey.endsWith("\"")){
                        mKey = mKey.substring(1,mKey.length()-1);
                    }
                    dateKey.add(mKey);
                    Object obj = jsonObject.get(mKey);
                    if (obj != null && !(obj instanceof LocalDateTime || obj instanceof Timestamp)){
                        dateKey.remove(mKey);
                    }
                }
            }
            for (int i = 0; i < dateKey.size(); i++) {
                String key = dateKey.get(i);
                Object obj = jsonObject.get(key);
                if (obj != null && obj instanceof LocalDateTime){
                    LocalDateTime localDateTime = (LocalDateTime) obj;
                    Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();

                    SimpleDateFormat formatter = new SimpleDateFormat(queryWrapper.getDefaultDateFormat());
                    String dateValue = formatter.format(Date.from(instant));
                    jsonObject.put(key,dateValue);
                }else if (obj != null && obj instanceof Timestamp){
                    LocalDateTime localDateTime = ((Timestamp) obj).toLocalDateTime();
                    Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();

                    SimpleDateFormat formatter = new SimpleDateFormat(queryWrapper.getDefaultDateFormat());
                    String dateValue = formatter.format(Date.from(instant));
                    jsonObject.put(key,dateValue);
                }else if(obj != null && !(obj instanceof LocalDateTime)){
                    dateKey.remove(i);
                    i--;
                }
            }
        }
    }


    public Long lgCount(LGLeftJoinQueryWrapper queryWrapper){
        Long count = getBaseMapper().allCount(queryWrapper.getQueryModel());
        return count;
    };


    public List<JSONObject> lgListMap(LGLeftJoinQueryWrapper queryWrapper){
        List<JSONObject> list = getBaseMapper().pageList(queryWrapper.getQueryModel());
        if (queryWrapper.getDefaultDateFormat() != null){
            convertJsonDateValue(list,queryWrapper);
        }
        return list;
    };

    public JSONObject lgOneMap(LGLeftJoinQueryWrapper queryWrapper){
        List<JSONObject> list = getBaseMapper().pageList(queryWrapper.getQueryModel());
        if (queryWrapper.getDefaultDateFormat() != null){
            convertJsonDateValue(list,queryWrapper);
        }
        if (list==null){
            return null;
        }
        if (list.size() > 1){
            throw new RuntimeException("lgOneMap error:when list.size() > 1");
        }
        return list.get(0);
    };



    /**
     * 删除产品出库
     * @param recordIds
     * @return
     */
    @Transactional
    public Result deleteRecordIds(Long[] recordIds){
        QueryWrapper<WmStockOut> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("record_id",recordIds);
        queryWrapper.select("item_need_id");
        List<WmStockOut> deleteList = wmStockOutService.list(queryWrapper);

        if (deleteList != null){
            for (int i =0;i < deleteList.size();i++){
                QueryWrapper<WmStockOut> queryWrapper1 = new QueryWrapper<>(deleteList.get(i));
                Long count = wmStockOutService.count(queryWrapper1);
                if (count == 0){
                    ProItemNeed proItemNeed = proItemNeedService.getById(deleteList.get(i).getItemNeedId());
                    if (proItemNeed != null){
                        proItemNeed.setShippedType(10L);
                        proItemNeedService.updateById(proItemNeed);
                    }
                }
            }
        }

        ArrayList<WmItemRecptLine> list = new ArrayList<>();
        for (int i = 0; i < recordIds.length; i++) {
            WmStockOut wmStockOut = wmStockOutService.getById(recordIds[i]);
            //统计出库
            WmItemRecptLine itemRecptLine = wmItemRecptLineService.getById(wmStockOut.getItemRecptLineId());
            list.add(itemRecptLine);
            if (itemRecptLine != null){
                Double ss =  wmStockOut.getQuantity().doubleValue();
                if (itemRecptLine.getQuantityOut() != null){
                    ss = itemRecptLine.getQuantityOut().doubleValue() - ss;
                }
                itemRecptLine.setQuantityOut(BigDecimal.valueOf(ss));
                wmItemRecptLineService.updateById(itemRecptLine);

            }
        }

        wmStockOutService.delete(recordIds);

        //更新入库记录的出库数量
        for (int i = 0;i < list.size();i++){
            wmItemRecptLineService.updateItemRecptLineOutQuantity(list.get(i).getLineId());
        }

        return Result.ERROR(0,"");
    }


    @Override
    public WmStockOut findOld(WmStockOut model) {
        return getById(model.getRecordId());
    }

    @Override
    public List<WmStockOut> getFromIds(Serializable[] ids) {
        QueryWrapper<WmStockOut> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("record_id",ids);
        return list(queryWrapper);
    }
}
